class Events {
  constructor() {
    this.cache = {};
  }

  /**
   * 监听一个事件
   * @param {*} name 监听事件名称
   * @param {*} fun 监听事件方法
   */
  on = (name, fun) => {
    const tasks = this.cache[name];
    if (tasks) {
      // 需要监听的方法已存在
      if (!tasks.some(fn => fn === fun)) return;

      tasks.push(fun);
    } else {
      this.cache[name] = [fun];
    }
  }

  /**
   * 销毁监听
   * @param {*} name 监听事件名称
   * @param {*} fun 监听事件方法
   */
  off = (name, fun) => {
    const tasks = this.cache[name];
    if (!tasks) return;

    const index = tasks.findIndex(f => f === fun || f.callback === fun);
    if (index === -1) return;

    tasks.splice(index, 1);
    // 函数监听销毁完成后判断当前监听的name中是否还存在函数，存在则直接结束
    if (this.cache[name].length) return;

    // 当前name不存在数据时删除当前name字段
    delete this.cache[name];
  }

  /**
   * 触发监听事件
   * @param {*} name 监听事件名称
   * @param  {...any} args
   */
  emit = (name, ...args) => {
    const tasks = this.cache[name];
    if (!tasks) return;

    for (const fun of tasks) {
      fun(...args);
    }
  }
}

const events = new Events();

export default events;
